# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from odoo import api, fields, models, _
import datetime


INVOIVCE_TYPE_SELECTION = [
    ('vat_special', '增值税专用发票'),
    ('vat_general', '增值税普通发票'),
    ('vat_general_e', '增值税普通发票(电子)'),
    ('vat_special_e', '增值税电子专用发票'),
    ('vat_traffic', '货物运输业增值税专用发票'),
    ('vat_vehicle', '机动车销售统一发票'),
    ('vat_general_roll', '增值税普通发票(卷式)'),
    ('vat_toll', '通行费发票'),
    ('vat_vehicle_2', '二手车发票'),
    ('vat_block_chain', '区块链电子发票'),  # 只支持深圳地区
    ('vat_special_ex', '全电专票'),
    ('vat_general_ex', '全电普票'),
]


class FapiaoPaper(models.Model):
    _name = "fp.fapiao.paper"
    # _inherit = ['mail.thread', 'mail.activity.mixin']
    _description = "Fapiao Paper"
    _order = 'date_fapiao desc, time_fapiao desc, id desc'

    name = fields.Char(
        string='Fapiao Name', required=True, copy=False, readonly=True,
        default=lambda self: _('New'),
        help="系统管理用")

    state = fields.Selection(selection=[
        ('draft', 'Draft'),
        ('confirmed', 'Confirmed'),
        ('doing', 'Doing'),

        ('error', 'Error'),
        ('done', 'Done'),  # 发票的正常稳定状态
        ('refunded', 'refunded'),  # 发票的被红冲稳定状态
        ('be_invalid', 'be_invalid'),  # 发票的被作废稳定状态

        ('posted', 'Posted'),
        ('cancel', 'Cancelled'),
    ], string='Status', required=True, readonly=True, copy=False, default='draft',
        help="系统管理用")

    type = fields.Selection(
        selection=[
            ('out_invoice', '销项蓝票'),
            ('out_refund', '销项红票'),
            ('in_invoice', '进项蓝票'),
            ('in_refund', '进项红票'),
        ], string='Type',
        required=True, index=True, readonly=True,
        default='in_invoice',
        help="系统管理用")

    attachment_id = fields.Many2one(
        'ir.attachment', string='Attachment', readonly=True)

    company_id = fields.Many2one(
        'res.company', 'Company', required=True, readonly=True, index=True,
        default=lambda self: self.env.company,
        help="系统管理用")

    user_id = fields.Many2one(
        'res.users', string='User', readonly=True, index=True, default=lambda self: self.env.user)

    invoice_type = fields.Selection(
        selection=INVOIVCE_TYPE_SELECTION,
        string='Fapiao Type', readonly=True, default='vat_general_e',
        help="票面信息")

    time_fapiao = fields.Datetime(
        string='Fapiao Time', readonly=True, index=True, copy=False,
        help="销项票使用, 开票时间")

    date_fapiao = fields.Date(
        string='Fapiao Date', readonly=True, index=True, copy=False,
        help="票面信息")

    invoice_code = fields.Char(
        string='Fapiao Code', readonly=True, copy=False, index=True,
        help="1 国地税; 2-5 行政区 6-7 年, 8 行业, 9-12 发票种类")

    # 发票代码 . todo 发票种类
    # 0 1100 21 0 0111
    # 011002100111
    #
    # 1为国家税务局、2为地方税务局，0为总局
    # 1工业、2商业、3加工修理修配业、4收购业、5水电业、6其他；
    # 地税行业划分：1交通运输业、2建筑业、3金融保险业、4邮电通信业、5文化体育业、6娱乐业、
    # 7服务业、8转让无形资产、9销售不动产、0表示其他

    invoice_number = fields.Char(
        string='Fapiao Number', readonly=True, copy=False, index=True)

    check_code = fields.Char(
        string='Check Code', readonly=True, copy=False, index=True)
    taxmachine_code = fields.Char(
        string='机器编号', readonly=True, copy=False, help="票面信息")

    note = fields.Text(string='Description', readonly=True, help="备注")
    payee_name = fields.Char(
        string='收款人', readonly=True, copy=False, help="票面信息")
    checker_name = fields.Char(
        string='复核', readonly=True, copy=False, help="票面信息")
    drawer_name = fields.Char(
        string='开票人', readonly=True, copy=False, help="票面信息")

    # 进项票, OCR之后, 直接获得结果
    # 进项票, 查验之后, 更新结果
    # 销项票, 录入之后, 直接计算获得结果
    amount_untaxed = fields.Float(string='Untaxed Amount', readonly=True)
    amount_tax = fields.Float(string='Tax', readonly=True)
    amount_total = fields.Float(string='Total', readonly=True)

    cn_amount_total = fields.Char(string='CN Total', readonly=True)

    buyer_id = fields.Many2one(
        'fp.partner', string='Buyer', readonly=True,
        required=False, index=True, help="票面信息")

    saler_id = fields.Many2one(
        'fp.partner', string='Saler', readonly=True,
        required=False, index=True, help="票面信息")

    buyer_name = fields.Char(
        string='Buyer Name', related='buyer_id.fapiao_name', store=True)
    buyer_tin = fields.Char(
        string='Buyer TIN', related='buyer_id.tin', store=True)
    buyer_address = fields.Char(
        string='Buyer Address', related='buyer_id.address')
    buyer_phone = fields.Char(
        string='Buyer Phone', related='buyer_id.phone')
    buyer_bank_name = fields.Char(
        string='Buyer Bank Name', related='buyer_id.bank_name')
    buyer_acc_number = fields.Char(
        string='Buyer Bank Account', related='buyer_id.acc_number')

    buyer_address_phone = fields.Char(
        string='Buyer Address Phone', related='buyer_id.address_phone',
        help="进项票时, 如何拆分为地址和电话")
    buyer_bank_account = fields.Char(
        string='Buyer Bank And Account', related='buyer_id.bank_account',
        help="进项票时, 如何拆分为银行和账号")

    saler_name = fields.Char(
        string='Saler Name', related='saler_id.fapiao_name', store=True)
    saler_tin = fields.Char(
        string='Saler TIN', related='saler_id.tin', store=True)
    saler_address = fields.Char(
        string='Saler Address', related='saler_id.address')
    saler_phone = fields.Char(
        string='Saler Phone', related='saler_id.phone')
    saler_bank_name = fields.Char(
        string='Saler Bank Name', related='saler_id.bank_name')
    saler_acc_number = fields.Char(
        string='Saler Bank Account', related='saler_id.acc_number')

    saler_address_phone = fields.Char(
        string='Saler Address Phone', related='saler_id.address_phone')
    saler_bank_account = fields.Char(
        string='Saler Bank And Account', related='saler_id.bank_account')

    line_ids = fields.One2many(
        'fp.fapiao.paper.line', 'fapiao_id', string='Fapiao Lines',
        readonly=True, auto_join=True)

    #
    # CRUD
    #

    def _attachment_vals_get(self, vals, res_id=None):
        attach_vals = vals.copy()
        attach_vals['res_model'] = self._name
        attach_vals['res_field'] = 'attachment_id'
        if res_id:
            attach_vals['res_id'] = res_id
        return attach_vals

    def _update_name(self):
        for one in self:
            if not one.name or one.name == _('New'):
                now = datetime.datetime.now()
                now1 = now.strftime('%Y%m%d')
                one.name = now1 + str(one.id).rjust(12, '0')

    @api.model_create_multi
    def create(self, vals_list):
        attch_vals_list = []
        for vals in vals_list:
            attachment_id = vals.get('attachment_id')
            attch_vals_list.append(attachment_id)
            if attachment_id and isinstance(attachment_id, dict):
                del vals['attachment_id']

        records = super().create(vals_list)

        todo_attch_vals_list = []
        todo_records = []
        for attach, one in zip(attch_vals_list, records):
            if attach and isinstance(attach, dict):
                attach2 = self._attachment_vals_get(attach, one.id)
                todo_attch_vals_list.append(attach2)
                todo_records.append(one)

        attachs = self.env['ir.attachment'].create(todo_attch_vals_list)
        for one, attach in zip(todo_records, attachs):
            one.attachment_id = attach.id

        records._update_name()

        return records

    def write(self, vals):
        attachment_id = vals.get('attachment_id')
        if attachment_id:
            if attachment_id and isinstance(attachment_id, dict):
                attach_vals = self._attachment_vals_get(attachment_id, self.id)
                if not self.attachment_id:
                    attach = self.attachment_id.create(attach_vals)
                    vals['attachment_id'] = attach.id
                else:
                    self.attachment_id.write(attach_vals)
                    del vals['attachment_id']

        res = super().write(vals)
        return res

    def unlink(self):
        self2 = self.filtered(lambda r: r.state in ['draft', 'cancel'])
        return super(FapiaoPaper, self2).unlink()

    #
    # Actions
    #

    def action_confirm(self):
        self2 = self.search([('id', 'in', self.ids), ('state', '=', 'draft')])
        for one in self2:
            one.write({'state': 'confirmed'})

    def action_cancel(self):
        self2 = self.search([('id', 'in', self.ids),
                             ('state', 'in', ['draft', 'confirmed'])])

        for one in self2:
            one.write({'state': 'cancel'})

    def action_draft(self):
        self2 = self.search([('id', 'in', self.ids), ('state', '=', 'cancel')])
        for one in self2:
            one.write({'state': 'draft'})
